<?php
/**
 * 微信支付
 */

namespace app\services;

use app\model\Change;
use app\model\CommodityOrder;
use app\model\InstallmentBillModel;
use app\model\ShopOrderModel as Order;
use app\model\SocialChange;
use app\model\UserModel as User;
use app\model\UserMoneyModel as UserMoney;
use exceptions\ApiException;
use Songshenzong\Support\Time;
use think\exception\HttpException;
use think\facade\Db;
use utils\WxPay;

/**
 * Class balancePayServices
 * @package app\services
 * @method $this data($data)
 * @method $this trade_type(string $trade_type)
 * @method $this userId(int $userId)
 */
class BalancePayServices
{

    /**
     * 用户id
     * @var
     */
    protected $userId;

    /**
     * 数据体
     * @var
     */
    protected $data;

    protected static $instance = null;

    public static function instance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    /**
     * 余额支付
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUnifiedOrder()
    {
        $userId = $this->userId;
        $user = \app\model\User::lock(true)->where(['id' => $userId])->find();
        if (!$user || !$this->data)
            return app('json')->json_error('支付失败');
        Db::startTrans();
        try {
            $body = $total_amount = $remarks = '';
            switch ($this->data['order_type']) {
                case 2: // 充值599会员
                    $change_type = 3;
                    $total_amount = 699;
                    if ($total_amount != $this->data['money']) {
                        Db::rollback();
                        return app('json')->json_error('金额错误');
                    }
                    if ($user->money < $total_amount) {
                        Db::rollback();
                        return app('json')->json_error('余额不足');
                    }
                    $user->vip = 1;
                    $user->vip_time = date('Y-m-d H:i:s', strtotime("+1 year"));
                    break;
                case 4: // 充值2980会员
                    $change_type = 3;
                    $total_amount = 2980;
                    if ($total_amount != $this->data['money']) {
                        Db::rollback();
                        return app('json')->json_error('金额错误');
                    }
                    if ($user->money < $total_amount) {
                        Db::rollback();
                        return app('json')->json_error('余额不足');
                    }
                    $user->vip = 2;
                    $user->vip_time = date('Y-m-d H:i:s', strtotime("+1 year"));
                    break;
                case 3: //购买商品
                    //下单
                    $change_type = 1;
                    $result = app()->make(CommodityOrder::class)->Pay($this->data, 3);
                    if (empty($result['order_id']) || $result['total_price'] == 0 || ($result['total_price'] != $this->data->data['money'])) {
                        return app('json')->json_error('下单失败！3');
                    }
                    $order_sn = implode(',', $result['order_id']);
                    $body = '购买商品';
                    $total_amount = $result['total_price'];
                    $remarks = $order_sn;
                    CommodityOrder::payDoneOrderCallback($userId, $remarks);
                    break;
            }
            Change::SetUserMoney($userId, $user->money, $total_amount, $change_type, 2);
            $user->money -= $total_amount;
            $user->save();
            $out_trade_no = rand(1000000000, 9999999999) . (string)date('ymdhis', time()) . (int)microtime(true); // 订单号
            $trade_type = $this->data['trade_type'];
            $order_type = $this->data['order_type'];
            $pay_way = $this->data['channel'];
            $voucher_img = '';
            $this->setPaymentOrder(compact('body', 'out_trade_no', 'total_amount', 'remarks', 'userId', 'trade_type', 'order_type', 'pay_way', 'voucher_img'), 1);
            Db::commit();
            return app('json')->json_success('支付成功');
        } catch (\Exception $e) {
            Db::rollback();
            return app('json')->json_error('支付失败' . $e->getMessage() . $e->getLine());
        }
    }

    public function setPaymentOrder(array $param, int $pay_way = 1)
    {
        $insert = [
            'total_fee' => $pay_way == 1 ? $param['total_amount'] : $param['total_amount'] / 100,
            'trade_type' => $param['trade_type'],
            'body' => $param['body'],
            'state' => 6,
            'pay_at' => date('Y-m-d H:i:s', time()),
            'out_trade_no' => $param['out_trade_no'],
            'pay_way' => $param['pay_way'],
            'remarks' => $param['remarks'],
            'order_type' => $param['order_type'],
            'user_id' => $param['userId'],
            'voucher_img' => $param['voucher_img'],
        ];
        Db::name('payment')->insert($insert);
    }

    /**
     * 魔术方法
     * @param $name
     * @param $arguments
     * @return $this
     */
    public function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        if ($name == 'data') {
            $this->{$name} = $arguments[0];
        } else {
            $this->{$name} = $arguments[0];
        }
        return $this;
    }
}